/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.util;

import com.jphenix.standard.docs.ClassInfo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 字节处理工具
 * 
 * 2019-07-29 增加了字节数组转为16进制字符串的方法
 * 2019-08-17 增加了替换字节数组中某一段
 * 2019-08-19 完善了替换字节数组某一段的方法
 * 
 * @author 刘虻
 * 2008-4-22下午05:30:39
 */
@ClassInfo({"2019-08-17 15:21","字节处理工具"})
public class ByteUtil {

	public final static int DEFAULT_BUFFER = 51200; //默认缓存大小 
	
	/**
	 * 构造函数
	 * 2008-4-22下午05:30:39
	 */
	public ByteUtil() {
		super();
	}
	
	/**
	 * 替换字节数组中指定段
	 * @param content  字节数组内容
	 * @param srcStr   需要替换的字符串
	 * @param objStr   替换成字符串
	 * @return         替换后的字节数组
	 * 2019年8月17日
	 * @author MBG
	 */
	public static byte[] swap(byte[] content,String srcStr,String objStr) {
		if(srcStr==null || srcStr.length()<1 || objStr==null || objStr.length()<1) {
			return content;
		}
		return swap(content,srcStr.getBytes(),objStr.getBytes());
	}
	
	/**
	 * 替换字节数组中指定段
	 * @param content  字节数组内容
	 * @param sors   需要替换的字节数组
	 * @param objs   替换成字节数组
	 * @return         替换后的字节数组
	 * 2019年8月17日
	 * @author MBG
	 */
	public static byte[] swap(byte[] content,byte[] sors,byte[] objs) {
		//构建输出流返回值
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		swap(content,sors,objs,bos);
		return bos.toByteArray();
	}
	
	/**
	 * 替换字节数组中指定段
	 * @param content 字节数组内容
	 * @param srcs    需要替换的字节数组
	 * @param objs    替换成字节数组
	 * @param os      输出流
	 * @return        处理是否成功
	 * 2019年8月17日
	 * @author MBG
	 */
	public static boolean swap(byte[] content,byte[] srcs,byte[] objs,OutputStream os) {
		if(content==null || content.length<1) {
			return false;
		}
		//构建读入流
		ByteArrayInputStream bis = new ByteArrayInputStream(content);
		return swap(bis,os,srcs,objs,DEFAULT_BUFFER);
	}
	
	/**
	 * 替换字节数组中指定段
	 * @param is         读入流
	 * @param os         输出流
	 * @param srcs       需要替换的字节数组
	 * @param objs       替换成字节数组
	 * @return           处理是否成功
	 * 2019年8月17日
	 * @author MBG
	 */
	public static boolean swap(InputStream is,OutputStream os,byte[] srcs,byte[] objs) {
		return swap(is,os,srcs,objs,DEFAULT_BUFFER);
	}
	
	/**
	 * 替换字节数组中指定段
	 * @param is         读入流
	 * @param os         输出流
	 * @param srcs       需要替换的字节数组
	 * @param objs       替换成字节数组
	 * @param bufferSize 缓存大小
	 * @return           处理是否成功
	 * 2019年8月17日
	 * @author MBG
	 */
	public static boolean swap(InputStream is,OutputStream os,byte[] srcs,byte[] objs,int bufferSize) {
		try {
			if(is==null || os==null) {
				return false;
			}
			if(bufferSize<srcs.length) {
				bufferSize = DEFAULT_BUFFER;
			}
			int    wCount       = 0;                     //写入字节数
			byte[] wBuffer      = new byte[bufferSize];  //写入缓存
			if(srcs==null || srcs.length<1 || objs==null || objs.length<1) {
				try {
					while ((wCount=is.read(wBuffer))!=-1) {
						os.write(wBuffer, 0, wCount);
					}
					return true;
				}catch(Exception e) {
					e.printStackTrace();
					return false;
				}finally {
					try {
						is.close();
					}catch (Exception ex) {}
					is = null;
					try {
						os.flush();
					}catch (Exception ex) {}
					try {
						os.close();
					}catch (Exception ex) {}
					os = null;
				}
			}
			int    rCount;                               //读取字节数
			int    matchIndex   = 0;                     //比对位置指针
			int    srcsLength   = srcs.length;           //比对字节数
			int    objsLength   = objs.length;           //替换字节数
			byte[] rBuffer      = new byte[bufferSize];  //读取缓存
			byte[] matchArrs    = new byte[srcs.length]; //匹配缓存
			while((rCount=is.read(rBuffer))!=-1) {
				for(int i=0;i<rCount;i++) {
					if(rBuffer[i]==srcs[matchIndex]) {
						matchArrs[matchIndex] = rBuffer[i];
						matchIndex++;
						if(matchIndex==srcsLength) {
							if(wCount+objsLength>bufferSize) {
								os.write(wBuffer,0,wCount);
								wCount = 0;
							}
							for(int j=0;j<objsLength;j++) {
								wBuffer[wCount++] = objs[j];
							}
							matchIndex = 0;
						}
						continue;
					}
					if(matchIndex>0) {
						if(wCount+matchIndex>bufferSize) {
							os.write(wBuffer,0,wCount);
							wCount = 0;
						}
						for(int j=0;j<matchIndex;j++) {
							wBuffer[wCount++] = matchArrs[j];
						}
					}
					matchIndex = 0;
					if(wCount+1>bufferSize) {
						os.write(wBuffer,0,wCount);
						wCount = 0;
					}
					wBuffer[wCount++] = rBuffer[i];
				}
			}
			if(wCount>0) {
				os.write(wBuffer,0,wCount);
			}
			return true;
		}catch(Exception e) {
			e.printStackTrace();
			return false;
		}finally {
			try {
				is.close();
			}catch(Exception ex) {}
			try {
				os.flush();
			}catch(Exception ex) {}
			try {
				os.close();
			}catch(Exception ex) {}
			os = null;
		}
	}
	
	/**
	 * 将字节数组转为16进制字符串
	 * @param data    需要转换的数据
	 * @return        转换后的字符串
	 * 2019年7月29日
	 * @author MBG
	 */
	public static String toHexString(byte[] data){
		//构建返回值
		StringBuffer res = new StringBuffer();
		if(data!=null){
			String ele; //转换后的元素
			for(int i=0;i<data.length;i++){
				ele = Integer.toHexString(data[i]);
				if(ele.length()>2) {
					ele = ele.substring(ele.length()-2);
				}else if(ele.length()<2){
					res.append("0");
				}
				res.append(ele);
			}
		}
		return res.toString();
	}
	
	/**
	 * 将字节数组中指定值转换为数值
	 * @author 刘虻
	 * 2008-4-22下午05:54:25
	 * @param bytes  数组
	 * @param fromId 数组起始位置
	 * @param toId   数组结束位置
	 * @return       转换值
	 */
	public static long getLong(byte[] bytes,int fromId,int toId) {
		if (bytes==null || bytes.length<toId) {
			return 0;
		}
		long reVal = 0; //构建返回值
		for(int i=fromId;i<toId+1;i++) {
			long tmpVal = bytes[i];//当前位值
			if (tmpVal<0) {
				tmpVal = 256+tmpVal;
			}
			for (int j=0;j<toId-i;j++) {
				tmpVal = tmpVal*16*16;
			}
			reVal += tmpVal;
		}
		return reVal;
	}
}
